package com.wang.springbootinit.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.springbootinit.common.ErrorCode;
import com.wang.springbootinit.exception.BusinessException;
import com.wang.springbootinit.exception.ThrowUtils;
import com.wang.springbootinit.mapper.StudentMapper;
import com.wang.springbootinit.model.dto.StudentBatchAddRequest;
import com.wang.springbootinit.model.dto.StudentRoleQueryRequest;
import com.wang.springbootinit.model.dto.StudentUpdateRequest;
import com.wang.springbootinit.model.dto.admin.AdminStudentQueryRequest;
import com.wang.springbootinit.model.entity.Student;
import com.wang.springbootinit.model.entity.Teacher;
import com.wang.springbootinit.model.entity.User;
import com.wang.springbootinit.model.vo.StudentVO;
import com.wang.springbootinit.service.StudentService;
import com.wang.springbootinit.service.UserService;
import com.wang.springbootinit.utils.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 学生服务实现类
 * 提供学生信息的增删改查等基础功能
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private UserService userService;

    @Override
    public Page<StudentVO> listStudents(int pageNum, int pageSize, StudentRoleQueryRequest queryRequest) {
        // 创建分页对象
        Page<Student> page = new Page<>(pageNum, pageSize);

        List<User> userList =new ArrayList<>();

        List<Integer> userRoles = queryRequest.getUserRole();
        if (CollUtil.isNotEmpty(userRoles)) {
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(User::getUserRole,userRoles);
            userList = userService.list(wrapper);
            if(CollUtil.isEmpty(userList)){
                return new Page<>(pageNum, pageSize);
            }
        }

        // 构建查询条件
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        if (queryRequest != null) {
            queryWrapper.eq( StringUtils.isNotBlank(queryRequest.getClassName()), Student::getClassName, queryRequest.getClassName())
                    .eq(queryRequest.getGender() != null, Student::getGender, queryRequest.getGender())
                    .eq(StringUtils.isNotBlank(queryRequest.getStudentNumber()),
                            Student::getStudentNumber, queryRequest.getStudentNumber())
                    .in(CollUtil.isNotEmpty(userList),Student::getUserId,userList.stream().map(User::getId).collect(Collectors.toList()))
                    .like(StringUtils.isNotBlank(queryRequest.getName()),
                            Student::getName, queryRequest.getName());
        }

        // 执行查询
        Page<Student> studentPage = studentMapper.selectPage(page, queryWrapper);
        // 转换为VO
        return convertToVOPage(studentPage);
    }

    @Override
    public Page<StudentVO> listStudents(AdminStudentQueryRequest queryRequest) {
        StudentRoleQueryRequest roleQueryRequest = new StudentRoleQueryRequest();
        roleQueryRequest.setName(queryRequest.getName());
        roleQueryRequest.setClassName(queryRequest.getClassName());
        roleQueryRequest.setGender(queryRequest.getGender());
        roleQueryRequest.setStudentNumber(queryRequest.getStudentNumber());
        roleQueryRequest.setUserRole(Collections.singletonList(0));
        return listStudents(queryRequest.getCurrent(),queryRequest.getPageSize(),roleQueryRequest);
    }

    @Override
    public StudentVO getStudentVOById(Long id) {
        Student student = studentMapper.selectById(id);
        ThrowUtils.throwIf(student == null, ErrorCode.NOT_FOUND_ERROR, "学生不存在");
        return convertToVO(student);
    }

    @Override
    public Student getStudentByNumber(String studentNumber) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentNumber", studentNumber);
        Student student = getOne(queryWrapper);
        if(ObjectUtil.isNull(student)){
            throw new BusinessException(ErrorCode.STUDENT_NOT_EXIST);
        }
        return student;
    }

    @Override
    public Student getStudentByHttpRequest(HttpServletRequest request) {
        return userService.getLoginStudent(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStudent(StudentUpdateRequest updateRequest) {
        Student student = studentMapper.selectById(updateRequest.getId());
        ThrowUtils.throwIf(ObjectUtil.isNull(student), ErrorCode.NOT_FOUND_ERROR, "学生不存在");

        // 更新学生信息
        Student updateStudent = new Student();
        BeanUtils.copyProperties(updateRequest, updateStudent);
        return studentMapper.updateById(updateStudent) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteStudent(Long id) {
        Student student = studentMapper.selectById(id);
        ThrowUtils.throwIf(student == null, ErrorCode.NOT_FOUND_ERROR, "学生不存在");
        return studentMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addStudentsByClass(StudentBatchAddRequest addRequest) {
        // 检查学号是否已存在
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentNumber", addRequest.getStudentNumber());
        if (studentMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "学号已存在");
        }

        Student student = new Student();
        BeanUtils.copyProperties(addRequest,student);
        int insert = studentMapper.insert(student);

        if(insert > 0){
            //生成用户
            User user = new User();
            user.setUserName(student.getName());
            user.setUserAccount(student.getStudentNumber());
            user.setUserPassword(DigestUtils.encrypt("123456"));
            user.setUserRole(0);
            user.setStudentId(student.getId());
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            userService.save(user);


            student.setUserId(user.getId());
            return updateById(student);
        }
        return Boolean.FALSE;
    }

    /**
     * 获取当前登录学生
     * @param request
     * @return
     */
    @Override
    public StudentVO getCurrentStudent(HttpServletRequest request) {
        return  userService.getLoginStudentVO(request);
    }

    /**
     * 教师端-获取所有学生列表
     * @return
     */
    @Override
    public List<StudentVO> listAllStudents() {
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Student::getIsDelete,0);
        List<Student> studentList = list(queryWrapper);
        if(CollUtil.isEmpty(studentList)){
            return Collections.emptyList();
        }
        return studentList.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 将学生实体转换为VO
     */
    private StudentVO convertToVO(Student student) {
        if (student == null) {
            return null;
        }
        StudentVO vo = new StudentVO();
        BeanUtils.copyProperties(student, vo);
        // 设置班级名称
        vo.setClassName(student.getClassName());
        return vo;
    }

    /**
     * 将学生分页数据转换为VO分页数据
     */
    private Page<StudentVO> convertToVOPage(Page<Student> studentPage) {
        Page<StudentVO> voPage = new Page<>(studentPage.getCurrent(), studentPage.getSize(), studentPage.getTotal());
        List<StudentVO> voList = studentPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }


} 